<?php
/**
 * City
 *
 * Класс City обрабатывает данные, связанные с городами
 *
 */
class City extends ActiveRecord {
	public $tableName = 'city';
	public $pkName = 'ID_city';
	protected $arrSettings = array('created_at' => true);
	
	public static $minImortanceToView = 4;				// Минимальное значения важности города. Города, имеющие значения меньше нигде не отображаются.
	public static $PopularCitiesOnPage = 24;			// Количество популярных гродов на странице города
	public  $nearestCitiesCount = 4;					// Количество ближайших гордов в составе блока "популярные направления" на странице города
	public  $biggestCitiesCount = 4;					// Количество крупнейших гордов текущего региона в составе блока "популярные направления" на странице города
	public  $nearestRegCapitalsCount = 7;				// Максимальное количество столиц из соседних областей в составе блока "популярные направления" на странице города
	public  $nearestRegBiggestCount = 4;				// Количество крупнейших гордов из соседних областей в составе блока "популярные направления" на странице города
	public  $SecondNeigboursBiggestCount = 4;			// Количество крупнейших гордов от соседей соседей региона текущего города
  
  /**
   * Обновляет координаты существующего в БД города
   * 
   * @param string $cityName - Название города для обновления
   * @param float $latitude - широта
   * @param float $longitude - долгота
   */
  public function updateCityCoordinates($cityName, $latitude, $longitude) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	/// Дописать проверку, а может координаты уже стоят
  	$stmt = "UPDATE `city` SET `latitude`='" . $latitude . "',`longitude`='" . $longitude . "' WHERE `city_name`='" . $cityName . "' AND (`latitude` IS NULL OR `longitude` IS NULL)";
  	$objDB->query($stmt);
  }
  
  /**
   * Устанавливает тип существующего в БД города
   *
   * @param string $cityName - Название города для обновления
   * @param int $city_type - тип города
   */
  public function updateCityType($cityName, $city_type) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "UPDATE `city` SET `city_type`='" . $city_type . "' WHERE `city_name`='" . $cityName . "' AND `city_type` IS NULL";
  	$objDB->query($stmt);
  }
  
  /**
   * Возвращает id города по его имени
   *
   * @param string $cityName - Название города для обновления
   */
  public function getIdByName($cityName) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "SELECT `city`.`ID_city` FROM `city` WHERE `city_name`='" . $cityName . "'";
  	return $objDB->selectSimpleField($stmt);
  }
  
  /**
   * Возвращает имя города по его id
   *
   * @param int $id - Id города
   */
  public function getNameById($id) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "SELECT `city`.`city_name` FROM `city` WHERE `ID_city`='" . $id . "'";
  	return $objDB->selectSimpleField($stmt);
  }
  
  /**
   * Возвращает id города по его имени и типу
   *
   * @param string $cityName - Название города для обновления
   */
  public function getIdByNameAndCityType($cityName,$cityType) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "SELECT `city`.`ID_city` FROM `city` WHERE `city_name`='" . $cityName . "' AND (`city_type`='" . $cityType . "' OR `city_type` IS NULL)";
  	return $objDB->selectSimpleField($stmt);
  	 
  }
  
  public function markAsNoParse($cityName,$cityType) {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "UPDATE `city` SET `city`.`no_parse`= 1 WHERE `city_name`='" . $cityName . "' AND `city_type`='" . $cityType . "'";
  	$objDB->query($stmt);
  }
  
  /**
   * Функция получает название региона для города 
   */
  public function getRegion() {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance(); //Получаем подключение к БД
  	$stmt = "SELECT `region`.`region_name`,`region`.`region_url` FROM `city` INNER JOIN `region` USING(`ID_region`) WHERE `city`.`ID_city`='" . $this->id . "'";
  	return $objDB->selectOne($stmt);
  }
  
  public function getPopularCities() {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance();
  	
  	$yetFindIds = array($this->id);	// массив id уже найденных городов
  	$fullResult = array();
  	
  	// Получаем ближайщие по координатам города
  	$stmt = "SELECT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`federal_district`.`federal_district_url`, 6371 * ACOS(SIN(" . $this->getField('latitude') . " * PI() / 180) * SIN(`city`.`latitude` * PI() / 180) + COS(" . $this->getField('latitude') . " * PI() / 180) * COS(`city`.`latitude` * PI() / 180) * COS(" . $this->getField('longitude') . " * PI() / 180 - `city`.`longitude` * PI() / 180)) AS `distance` 
  			FROM `city`
  			INNER JOIN `federal_district` USING(`ID_federal_district`)
  			WHERE `city`.`ID_federal_district` IS NOT NULL AND `city`.`longitude` IS NOT NULL AND `city`.`latitude` AND `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "' 
  			ORDER BY `distance` ASC 
  			LIMIT " . $this->nearestCitiesCount;
  	$fullResult =  $objDB->select($stmt);

  	$yetFindIds = array_merge($yetFindIds,Service_ArrayConverter::getColumn($fullResult, 'ID_city'));
 
  	// Получаем крупнейшие города региона
  	$stmt = "SELECT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`city`.`population`,`federal_district`.`federal_district_url`
		  	FROM `city`
		  	INNER JOIN `federal_district` USING(`ID_federal_district`)
		  	WHERE `city`.`ID_region`='" . $this->getField('ID_region') .  "' AND `city`.`ID_federal_district` IS NOT NULL AND `city`.`longitude` IS NOT NULL AND `city`.`latitude` AND `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "' 
		  	ORDER BY `city`.`population` DESC
		  	LIMIT " . $this->biggestCitiesCount;
  	$result =  $objDB->select($stmt);

  	$yetFindIds = array_merge($yetFindIds,Service_ArrayConverter::getColumn($result, 'ID_city'));
  	$fullResult = array_merge($fullResult, $result);

  	// Получаем столицы соседних регионов города
  	$stmt = "SELECT DISTINCT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`federal_district`.`federal_district_url`
		  	FROM `region`
		  	INNER JOIN `federal_district` USING(`ID_federal_district`)
		  	INNER JOIN `near_region` ON IF(`near_region`.`ID_one_region`='" . $this->getField('ID_region') . "',`near_region`.`ID_another_region`=`region`.`ID_region`,`near_region`.`ID_one_region`=`region`.`ID_region`)
		  	INNER JOIN `city` ON `city`.`city_name`=`region`.`region_center`
		  	WHERE (`near_region`.`ID_one_region`='" . $this->getField('ID_region') .  "' OR  `near_region`.`ID_another_region`='" . $this->getField('ID_region') . "') AND `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "'
		  	LIMIT " . $this->nearestRegCapitalsCount;
  	$result =  $objDB->select($stmt);

  	$yetFindIds = array_merge($yetFindIds,Service_ArrayConverter::getColumn($result, 'ID_city'));
  	$fullResult = array_merge($fullResult, $result);
  	
  	// Получаем крупнейшие города соседних регионов
  	$stmt = "SELECT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`city`.`population`,`federal_district`.`federal_district_url`
  			FROM `city`
  			INNER JOIN `federal_district` USING(`ID_federal_district`)
  			WHERE  `city`.`ID_region` IN(
  										SELECT IF(`near_region`.`ID_one_region`='" . $this->getField('ID_region') .  "',`near_region`.`ID_another_region`,`near_region`.`ID_one_region`) as `ID_region`
									  	FROM `near_region`
									  	WHERE (`near_region`.`ID_one_region`='" . $this->getField('ID_region') .  "' OR  `near_region`.`ID_another_region`='" . $this->getField('ID_region') . "')
									  ) AND `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "' 
			ORDER BY `city`.`population` DESC 
		  	LIMIT " . $this->nearestRegBiggestCount;
  	$result =  $objDB->select($stmt);

  	$yetFindIds = array_merge($yetFindIds,Service_ArrayConverter::getColumn($result, 'ID_city'));
  	$fullResult = array_merge($fullResult, $result);
  			
  	
  	// Получаем крупнейшие города соседей соседей, исключая возможность попадания текущего региона в этот список
  	// !!!!Начиная отсюда города будут относится не к "ближайшим", а к "остальным"
  	$stmt = "
  			SELECT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`city`.`population`,`federal_district`.`federal_district_url`
  			FROM `city`
  			INNER JOIN `federal_district` USING(`ID_federal_district`)
  			WHERE `city`.`ID_region` IN(
							  			SELECT DISTINCT IF(`first_neighbours`.`ID_region`=`near_region`.`ID_one_region`,`near_region`.`ID_another_region`,`near_region`.`ID_one_region`) as id
							  			FROM `near_region`
							  			INNER JOIN (
												  	SELECT IF(`near_region`.`ID_one_region`='" . $this->getField('ID_region') .  "',`near_region`.`ID_another_region`,`near_region`.`ID_one_region`) as `ID_region`
												  	FROM `near_region`
												  	WHERE (`near_region`.`ID_one_region`='" . $this->getField('ID_region') .  "' OR  `near_region`.`ID_another_region`='" . $this->getField('ID_region') . "')
									  	) first_neighbours
					  					ON `first_neighbours`.`ID_region` = `near_region`.`ID_one_region` OR `first_neighbours`.`ID_region` = `near_region`.`ID_another_region` 
					  					WHERE `near_region`.`ID_one_region` !='" . $this->getField('ID_region') .  "' AND `near_region`.`ID_another_region` != '" . $this->getField('ID_region') ."'
			  							)
  			AND `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "'
  			ORDER BY `city`.`population` DESC 
		  	LIMIT " . $this->SecondNeigboursBiggestCount;
  	$result =  $objDB->select($stmt);
  	$yetFindIds = array_merge($yetFindIds,Service_ArrayConverter::getColumn($result, 'ID_city'));
  	
  	// Получаем дополнительные города
  	$stmt = "SELECT `city`.`ID_city`,`city`.`city_url`,`city`.`city_name`,`city`.`population`,`federal_district`.`federal_district_url`
	  		FROM `city`
	  		INNER JOIN `federal_district` USING(`ID_federal_district`)
	  		WHERE `city`.`ID_city` NOT IN(" . join(',', $yetFindIds) . ") AND `city`.`importance_level` >='" . City::$minImortanceToView . "'
	  		ORDER BY `city`.`population` DESC
	  		LIMIT " . (self::$PopularCitiesOnPage - count($fullResult));
  	
 	$result =  $objDB->select($stmt);
  	$fullResult = array_merge($fullResult, $result);

  	return $fullResult;
  	
  	//$stmt = "SELECT `city`.`city_name`,`city`.`city_url`,`city`.`city_type`,`city`.`importance_level`
  	//FROM `city`
  	//WHERE `city`.`ID_federal_district` ='" . $this->id  . "' AND `city`.`ID_city` !='" . $this->id . " AND `city`.`importance_level` >='" . self::$minImortanceToView . "' ORDER BY `city`.`importance_level` DESC, `city`.`city_type` DESC LIMIT " . $limit;
  }
  
  /**
   * Устанавливает городам с регионами importance_level в соответствие их населения и важности ФО, к которому они принадлежат
   */
  public function actionUpdateImportance() {
  	Service_Debug::setDebug();
  	$objDB = Service_Database::instance();
  	for($i = 1; $i < 84; $i++) {
  		$stmt = "SELECT city.city_name, city.ID_region, city.population, federal_district.importance_level, city.ID_city FROM city INNER JOIN federal_district USING(ID_federal_district) WHERE city.ID_region='" . $i . "' AND city.population > 0 ORDER BY 3 DESC";
  		$result = $objDB->select($stmt);
  		if(!empty($result)) {
  			for($j = 0; $j < count($result); $j++) {
  				echo $result[$j]['ID_region'] . ' ' .$result[$j]['city_name'] . ' ' . $result[$j]['population'] . '<br>';
  				$importanceLevel = 0;
  				if($j < 1) $importanceLevel = 5;
  				elseif($j < 3) $importanceLevel = 3;
  				elseif($j < 5) $importanceLevel = 2;
  				elseif($j < 10) $importanceLevel = 1;
  				$objDB->update('city', array('importance_level' => ($importanceLevel + $result[$j]['importance_level'])), array('ID_city' => $result[$j]['ID_city']));
  			}
  		}
  	}
  }
}
?>